package com.huika.dealontop.views;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;

import com.huika.dealontop.R;
import com.huika.dealontop.utils.UIUtils;

/**
 * 商品详情 布局
 */
public class TBLayout extends LinearLayout {
	private OnPullListener pullListener;
	private OnPageChangedListener ctListener;
	private OnFutureChangePageListener mFutureListener;
	private VelocityTracker vTracker;

	public void setOnPullListener(OnPullListener listener) {
		this.pullListener = listener;
	}

	public void setOnContentChangeListener(OnPageChangedListener ler) {
		this.ctListener = ler;
	}

	public void setFutureChangePageListener(OnFutureChangePageListener futureListener){
		this.mFutureListener = futureListener;
	}

	private View mHeader;
	private View mFooter;
	private Scroller scroller;
	private int mTouchSlop = 0;

	private int mLastY;
	private int mLastInterceptY;
	private int mHeaderHeight;

	public final static int SCREEN_HEADER = 11;
	public final static int SCREEN_FOOTER = 12;

	private int screen = SCREEN_HEADER;

	@SuppressLint("NewApi")
	public TBLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public TBLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public TBLayout(Context context) {
		super(context);
		init();
	}

	private void init() {
		scroller = new Scroller(getContext());
		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
	}

	@Override
	public void onWindowFocusChanged(boolean hasWindowFocus) {
		super.onWindowFocusChanged(hasWindowFocus);
		if (hasWindowFocus && mHeader == null && mFooter == null) {
			initData();
		}
	}

	private void initData() {
		mHeader = findViewById(R.id.tb_header);
		mFooter = findViewById(R.id.tb_footer);
		ViewGroup.LayoutParams lps = mFooter.getLayoutParams();
		mHeaderHeight = mHeader.getMeasuredHeight();
		lps.height = mHeaderHeight;
		mFooter.setLayoutParams(lps);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		boolean result = false;
		final int y = (int) ev.getY();
		switch (ev.getAction()) {
			case MotionEvent.ACTION_DOWN:
				mLastInterceptY = mLastY = y;
				getTracker();
				break;
			case MotionEvent.ACTION_MOVE:
				int dy = y - mLastInterceptY;
				if (dy > mTouchSlop && screen == SCREEN_FOOTER) {// pull down
					result = (pullListener != null && pullListener
							.footerHeadReached(ev));
				} else if (dy < -mTouchSlop && screen == SCREEN_HEADER) { // pull up
					result = (pullListener != null && pullListener
							.headerFootReached(ev));
				}
				break;
			case MotionEvent.ACTION_UP:
				mLastInterceptY = 0;
				break;
		}
		return result;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		final int y = (int) event.getY();
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				getTracker();
				break;
			case MotionEvent.ACTION_MOVE:
				vTracker.addMovement(event);
				computeFutureChange();
				int dy = y - mLastY;
				switch (screen) {
					case SCREEN_HEADER:
						int sy = -dy;
						if (sy < 0) {
							sy = 0;
						} else if (sy > getHeight()) {
							sy = getHeight();
						}
						scrollTo(0, sy);
						break;
					case SCREEN_FOOTER:
						if (dy > 0) {
							scrollTo(0, mHeaderHeight - dy);
						} else { // dy < 0
						}
						break;
				}
				break;
			case MotionEvent.ACTION_UP:
				vTracker.addMovement(event);
				if(!computeCurrentVelocity()){ //先计算活动速度
					//活动速度没有超出自动滑动范围，再计算活动距离
					computeCurrentDistance();
				}

				mLastY = 0;
				//vTracker.recycle();
				break;
			case MotionEvent.ACTION_CANCEL:
				vTracker.recycle();
				break;
		}
		return true;
	}

	private void computeFutureChange() {
		if(mFutureListener == null) return;
		int t = 0;
		switch (screen) {
            case SCREEN_HEADER:
                t = mHeaderHeight / 8;
                break;
            case SCREEN_FOOTER:
                t = mHeaderHeight * 7 / 8;
                break;
        }
		int sy = getScrollY();
		if (sy > t) { // scroll to footer
			mFutureListener.onFutureChangePage(SCREEN_FOOTER);
        } else { // scroll to header
			mFutureListener.onFutureChangePage(SCREEN_HEADER);
        }
	}

	private boolean computeCurrentVelocity() {
		vTracker.computeCurrentVelocity(1000);
		if(vTracker.getYVelocity() > UIUtils.dip2px(120)){ //向下活动的速度 120dp/秒
            scrollToHeader();
			return true;
        }else if(vTracker.getYVelocity() < - UIUtils.dip2px(120)){ //向上活动的速度 120dp/秒
            scrollToFooter();
			return true;
        }
		return false;
	}

	private void computeCurrentDistance() {
		int t = 0;
		switch (screen) {
            case SCREEN_HEADER:
                t = mHeaderHeight / 8;
                break;
            case SCREEN_FOOTER:
                t = mHeaderHeight * 7 / 8;
                break;
        }
		int sy = getScrollY();
		if (sy > t) { // scroll to footer
			scrollToFooter();
        } else { // scroll to header
			scrollToHeader();
        }
	}

	public void scrollToHeader() {
		int sy = getScrollY();
		scroller.startScroll(0, sy, 0, -sy, 1200);
		screen = SCREEN_HEADER;
		if (ctListener != null) {
            ctListener.onPageChanged(SCREEN_HEADER);
        }
		invalidate();
	}

	public void scrollToFooter() {
		int sy = getScrollY();
		scroller.startScroll(0, sy, 0, mHeaderHeight - sy, 1200);
		screen = SCREEN_FOOTER;
		if (ctListener != null) {
            ctListener.onPageChanged(SCREEN_FOOTER);
        }
		invalidate();
	}

	private void getTracker() {
		vTracker = VelocityTracker.obtain();
	}

	@Override
	public void computeScroll() {
		if (scroller.computeScrollOffset()) {
			scrollTo(scroller.getCurrX(), scroller.getCurrY());
			postInvalidate();
		}
	}

	public interface OnPullListener {
		// 手指向上滑动时到达第一页底部
		boolean headerFootReached(MotionEvent event);

		// 手指向下滑动时到达第二页顶部
		boolean footerHeadReached(MotionEvent event);
	}

	public interface OnPageChangedListener {
		// 页面改变事件回调
		void onPageChanged(int stub);
	}

	/**
	 * 松开，将打开某个页面回调
	 */
	public interface OnFutureChangePageListener {
		void onFutureChangePage(int stub);
	}
}
